﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;

namespace FGrubert.CrmQueueMonitor.WinForms
{
    public abstract class QueueBase : INotifyPropertyChanged
    {
        private string _name;
        /// <summary>
        /// The name of the queue
        /// </summary>
        public string Name
        {
            get { return _name; }
            set
            {
                if (_name != value)
                {
                    _name = value;
                    NotifyPropertyChanged();
                }
            }
        }

        private Guid _queueId;
        /// <summary>
        /// The ID of the queue
        /// </summary>
        public Guid QueueId
        {
            get { return _queueId; }
            set
            {
                if (_queueId != value)
                {
                    _queueId = value;
                    NotifyPropertyChanged();
                }
            }
        }

        private double _hoursToYellow;
        /// <summary>
        /// Gets or sets the number of hours the oldest item can be until it is marked as yellow
        /// </summary>
        public double HoursToYellow
        {
            get { return _hoursToYellow; }
            set
            {
                if (_hoursToYellow != value)
                {
                    _hoursToYellow = value; ;
                    NotifyPropertyChanged();
                }
            }
        }

        private double _hoursToRed;
        /// <summary>
        /// Gets or sets the number of hours the oldest item can be until it is marked as red
        /// </summary>
        public double HoursToRed
        {
            get { return _hoursToRed; }
            set 
            {
                if (_hoursToRed != value)
                {
                    _hoursToRed = value;
                    NotifyPropertyChanged();
                }
            }
        }


        /// <summary>
        /// Returns the name of the Queue
        /// </summary>
        /// <returns>The name of the Queue</returns>
        public override string ToString()
        {
            return Name;
        }

        /// <summary>
        /// Event that is raised if a property changes
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Internal handling that a property has changed
        /// </summary>
        /// <param name="propertyName">The name of the property that changed. Can be empty, then the caller name will be used</param>
        protected void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Serialize an array of queue base objects to a string
        /// </summary>
        /// <param name="queues">And array of QueueBase</param>
        /// <returns>The array aerialized as a string</returns>
        public static string Serialize(QueueBase[] queues)
        {
            StringBuilder sb = new StringBuilder();
            XmlWriterSettings writerSettings = new XmlWriterSettings();
            writerSettings.Indent = true;
            writerSettings.OmitXmlDeclaration = true;
            using (XmlWriter writer = XmlWriter.Create(sb, writerSettings))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(QueueConfig[]));
                serializer.Serialize(writer, queues);
            }
            return sb.ToString();
        }

        /// <summary>
        /// Serialize an array of queue base objects to a xml document
        /// </summary>
        /// <param name="queues">And array of QueueBase</param>
        /// <returns>The array aerialized as a xml document</returns>
        public static XmlDocument SerializeToXmlNode(QueueBase[] queues)
        {
            string serialized = Serialize(queues);
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(serialized);
            return xmlDoc;
        }

        /// <summary>
        /// Deserializes a string back to an array of QueueBase
        /// </summary>
        /// <param name="str">The serialized array</param>
        /// <returns>An array of QueueBase</returns>
        public static QueueBase[] Deserialize(string str)
        {
            using (TextReader reader = new StringReader(str))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(QueueConfig[]));
                return (QueueConfig[])serializer.Deserialize(reader);
            }
        }

        /// <summary>
        /// Deserializes a xml document back to an array of QueueBase
        /// </summary>
        /// <param name="xmlDoc">The serialized xml document</param>
        /// <returns>An array of QueueBase</returns>
        public static QueueBase[] Deserialize(XmlDocument xmlDoc)
        {
            using (TextReader reader = new StringReader(xmlDoc.OuterXml))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(QueueConfig[]));
                return (QueueConfig[])serializer.Deserialize(reader);
            }
        }
    }
}
